#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
#include <MFRC522DriverPinSimple.h>

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <Ticker.h>

const char* ssid = "LIUYU";
const char* passwd = "12345678"; //WiFi密码
String url = "http://192.168.1.1o12:9000/ssm_module/swringCard.do"; //请求地址
WiFiClient tcp;
HTTPClient http;
Ticker timer;

//连线
//D5 - SCK
//D6 - MISO
//D7 - MOSI
//D8 - SDA(SS)
//GND - GND
//3V3 - 3.3V

/*
 * ESP8266 SPI默认引脚：variants\generic\common.h
 * #define PIN_SPI_SS   (15) D8
 * #define PIN_SPI_MOSI (13) D7
 * #define PIN_SPI_MISO (12) D6
 * #define PIN_SPI_SCK  (14) D5
 */
MFRC522DriverPinSimple ss_pin(D8); //配置片选引脚
MFRC522DriverSPI driver(ss_pin); //使用SPI接口
MFRC522 mfrc522(driver);  //读写器

void setup() {
  Serial.begin(74880);
  pinMode(LED_BUILTIN, OUTPUT); //初始化LED
  digitalWrite(LED_BUILTIN, HIGH); //默认关灯
  mfrc522.PCD_Init();  //初始化读写器
  WiFi.mode(WIFI_STA);
  WiFi.begin("LIUYU", "12345678"); //连接Wi-Fi
  while (!WiFi.isConnected())
  {
    delay(100);
  }
  Serial.println(WiFi.localIP()); //连接成功打印IP地址
  http.begin(tcp, url); //初始化HTTP客户端
  Serial.println(F("Scan PICC to see UID"));
}

void loop() {
  //判断是否有卡
  if ( !mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  //读取卡号
  if ( !mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  String uid;
  //将二进制UID转为16进制字符串
  for(int i = 0; i < mfrc522.uid.size; i++)
  {
    char hex[3];
    sprintf(hex, "%02X", mfrc522.uid.uidByte[i]);
    uid += String(hex);
  }

  //构造JSON报文
  String request;
  StaticJsonDocument<64> doc;
  doc["card_num"] = uid.c_str();
  serializeJson(doc, request);
  Serial.println(request);
  
  //发送请求消息
  http.addHeader("Content-Type", "application/json");
  int status = http.POST(request);
  Serial.println(status);
  if (status == 200)
  {
    String result = http.getString();
    Serial.println(result);
    //解析JSON报文
    StaticJsonDocument<96> doc;
    DeserializationError error = deserializeJson(doc, result);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
    }
    else {
      const char* card_num = doc["card_num"];
      if (strtol(card_num, NULL, 16) == strtol(uid.c_str(), NULL, 16))
      {
        int card_status = doc["card_status"]; // 0 不开；1 开
        if (card_status)
        {
          //开灯并启动定时器，5秒后关灯
          digitalWrite(LED_BUILTIN, LOW);
          timer.once_scheduled(5, [](){digitalWrite(LED_BUILTIN, HIGH);});
        }
      }
    }
  }
  //断开连接
  http.end();

  mfrc522.PICC_HaltA();
}
